﻿using System;
using System.IO;
using System.Reflection;
using BSpec.Document;
using BSpec.Specification;
using BSpec.Specs;
using NUnit.Framework;
using Rhino.Mocks;

namespace document_generator_specs
{
    namespace with_scenario_of
    {
        public abstract class generating_a_spec_document : SpecificationBase<DocumentGenerator>
        {
            protected Assembly spec_assembly;
            protected string document_file;
            protected IDocumentRenderer document_renderer;
            protected const string document_extension = ".html";

            protected override void setup_scenario()
            {
                given_a_document_renderer();
            }

            protected override DocumentGenerator create_subject()
            {
                return new DocumentGenerator(document_renderer);
            }

            private void given_a_document_renderer()
            {
                document_renderer = Dependency.Resolve(
                    MockRepository.GenerateStub<IDocumentRenderer>(), new HtmlRenderer());

                Dependency.RunForMock(() =>
                    document_renderer.Stub(d => d.FileExtension).Return(document_extension));
            }

            protected void given_a_spec_assembly()
            {
                spec_assembly = Assembly.GetExecutingAssembly();
                document_file = spec_assembly.GetName().Name + document_extension;
            }

            protected void given_no_file_currently_exists()
            {
                if (File.Exists(document_file))
                {
                    File.Delete(document_file);
                }
            }
        }
    }

    namespace given_a_spec_assembly.and_no_file_currently_exists
    {
        [TestFixture]
        public class when_generating_a_spec_document : with_scenario_of.generating_a_spec_document
        {
            protected override void setup_scenario()
            {
                base.setup_scenario();

                given_a_spec_assembly();
                given_no_file_currently_exists();
            }

            protected override void execute_scenario()
            {
                the_subject.WriteDocument(spec_assembly);
            }

            [Test]
            public void should_get_specifications_in_assembly()
            {
                Dependency.RunForMock(() =>
                    document_renderer.AssertWasCalled(d => d.Render(Arg<SpecificationDataSet>.Is.NotNull)));
            }

            [Test]
            public void should_render_document()
            {
                Dependency.RunForMock(() =>
                    document_renderer.AssertWasCalled(d => d.Render(Arg<SpecificationDataSet>.Is.Anything)));
            }

            [Test]
            public void should_create_document_file()
            {
                File.Exists(document_file).should_be_true();
            }
        }
    }
}
